package com.snopy.concurrency.atomic;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicMarkableReference;
import java.util.concurrent.atomic.AtomicStampedReference;

/**
 * @author snopy
 * @version 1.0.0
 * @classname ABADemo
 * @description
 * @email 77912204@qq.com
 * @date 2022/06/28 14:37
 */
@Slf4j
public class MarkABADemo {
    static AtomicMarkableReference<String> ref = new AtomicMarkableReference<>("A",true);
    
    public static void main(String[] args) throws InterruptedException {
        /*String prev = ref.getReference();
        boolean marked = ref.isMarked();
        other();
        TimeUnit.MILLISECONDS.sleep(200);
        log.debug("change A->C:{}",ref.compareAndSet(prev,"C",marked,false));*/
        Long myLong = 5L;
        Long anotherLong = 7L;
        AtomicMarkableReference<Long> atomicMarkableReference = new AtomicMarkableReference<>(myLong,false);
        //错误的期望值
        boolean wasSuccess = atomicMarkableReference.compareAndSet(myLong, anotherLong, true, true);
        log.debug("compare and set succeeded:{},currentvalue:{}",wasSuccess,atomicMarkableReference.getReference());
        //正确的期望值
        wasSuccess = atomicMarkableReference.compareAndSet(myLong, anotherLong, false, true);
        log.debug("compare and set succeeded:{},currentvalue:{}",wasSuccess,atomicMarkableReference.getReference());

    }
    private static void other() throws InterruptedException {
        new Thread(()->{
            String prev = ref.getReference();
            boolean marked = ref.isMarked();
            log.debug("change A->B:{}",ref.compareAndSet(prev,"B",marked,false));
        },"t1").start();
        TimeUnit.MILLISECONDS.sleep(200);
        new Thread(()->{
            String prev = ref.getReference();
            boolean marked = ref.isMarked();
            log.debug("change B->A:{}",ref.compareAndSet(prev,"A",marked,false));
        },"t1").start();
    }
}
